package com.jj.core.utils;

import java.util.LinkedList;
import java.util.List;

public enum JavaType {
    UNKNOWN(-1, ""),
    STRING(0, "String"),
    BYTE(1, "Byte"),
    SHORT(2, "Short"),
    INTEGER(3, "Integer"),
    LONG(4, "Long"),
    DOUBLE(5, "Double"),
    LISTINT(6, "List<Integer>"),
    LISTDOUBLE(7, "List<Double>");

    private int value;
    private String typeStr;

    JavaType(int value, String typeStr) {
        this.value = value;
        this.typeStr = typeStr;
    }


    public String getTypeStr() {
        return typeStr;
    }

    public static JavaType findByValue(int value) {
        switch (value) {
            case 0:
                return STRING;
            case 1:
                return BYTE;
            case 2:
                return SHORT;
            case 3:
                return INTEGER;
            case 4:
                return LONG;
            case 5:
                return DOUBLE;
            case 6:
                return LISTINT;
            case 7:
                return LISTDOUBLE;
            default:
                return UNKNOWN;
        }
    }

    public static JavaType findByString(String typeStr) {
        if (typeStr.equalsIgnoreCase("int")) {
            return INTEGER;
        } else if (typeStr.equalsIgnoreCase("string")) {
            return STRING;
        } else if (typeStr.equalsIgnoreCase("double")) {
            return DOUBLE;
        } else if (typeStr.equalsIgnoreCase("long")) {
            return LONG;
        } else if (typeStr.equalsIgnoreCase("byte")) {
            return BYTE;
        } else if (typeStr.equalsIgnoreCase("short")) {
            return SHORT;
        } else if (typeStr.toLowerCase().startsWith("list<int>")) {
            return LISTINT;
        } else if (typeStr.toLowerCase().startsWith("list<double>")) {
            return LISTDOUBLE;
        } else {
            return UNKNOWN;
        }
    }

    public static Object parse(String line, JavaType type) {
        switch (type) {
            case UNKNOWN:
                return null;
            case STRING:
                return line;
            case BYTE: {
                Double d = Double.parseDouble(line);
                return d.byteValue();
            }
            case SHORT: {
                Double d = Double.parseDouble(line);
                return d.shortValue();
            }
            case INTEGER: {
                Double d = Double.parseDouble(line);
                return d.intValue();
            }
            case LONG: {
                Double d = Double.parseDouble(line);
                return d.longValue();
            }
            case DOUBLE: {
                Double d = Double.parseDouble(line);
                return d;
            }
            case LISTINT: {
                List<Integer> list = new LinkedList<>();
                String[] lines = line.split(",");
                for (String lineStr : lines) {
                    if (lineStr.contains("-")) {
                        String[] subLines = lineStr.split("-");
                        Integer begin = Integer.parseInt(subLines[0]);
                        Integer end = Integer.parseInt(subLines[1]);
                        for (int i = begin; i <= end; i++) {
                            list.add(i);
                        }
                    } else {
                        Double d = Double.parseDouble(lineStr);
                        list.add(d.intValue());
                    }
                }
                return list;
            }
            case LISTDOUBLE: {
                List<Double> list = new LinkedList<>();
                String[] lines = line.split(",");
                for (String doubleStr : lines) {
                    list.add(Double.parseDouble(doubleStr));
                }
                return list;
            }
            default:
                return null;
        }
    }

    public static String toObjStr(Object obj, JavaType javaType) {
        StringBuffer sb = new StringBuffer();
        switch (javaType) {
            case UNKNOWN:
                return "Unknown type";
            case STRING:
            case BYTE:
            case SHORT:
            case INTEGER:
            case LONG:
            case DOUBLE:
                sb.append(obj.toString());
                break;
            case LISTINT: {
                sb.append("Integer[] array = ");
                List list = (List) obj;
                sb.append("{");
                for (int i = 0; i < list.size(); i++) {
                    sb.append(list.get(i).toString());
                    if (i != list.size() - 1) {
                        sb.append(",");
                    }
                }
                sb.append("}");
            }
            break;
            case LISTDOUBLE: {
                sb.append("Double[] array = ");
                List list = (List) obj;
                sb.append("{");
                for (int i = 0; i < list.size(); i++) {
                    sb.append(list.get(i).toString());
                    if (i != list.size() - 1) {
                        sb.append(",");
                    }
                }
                sb.append("}");
            }
            break;
            default:
                return "";
        }
        return sb.toString();
    }
}
